﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Collections;
using System.Reflection;
using Yd.CommCls;
using System.Configuration;

namespace Yd.Domain.Abstract
{
    public abstract class BaseCls
    {

        public delegate IList<object> GetList(object _model, int pagesize, int curpage, out int num);//代理执行的分页的方法
        public delegate IList<object> GetListTS(int pagesize, int curpage, out int num);//代理执行的分页的方法
        public delegate IList<object> GetList_Page(int pagesize, int curpage, out int num,out string _querystring);
        public string ConStr = ConfigurationManager.ConnectionStrings["XrConstr"].ConnectionString;

        /// <summary>
        /// 日志保存 
        /// </summary>
        /// <param name="_logcontent"></param>
        public virtual void LocalLog(string _logcontent)
        {

        }

        /// <summary>
        /// 执行存储过程总的方法
        /// </summary>
        /// <param name="_object"></param>
        /// <param name="_objectcount"></param>
        /// <param name="_storeproname"></param>
        /// <returns></returns>
        public virtual int InsertObject(object _object,int _objectcount,string _storeproname)
        {
            try
            {
                SqlParameter[] objectparam = new SqlParameter[_objectcount];
                FillModel(objectparam, _object);
                return ExecuteStorePro(_storeproname, objectparam);
            }
            catch (Exception e)
            {
                LocalLog(_storeproname+":"+e.Message);
                return -1;
            }
        }

        /// <summary>
        /// 通过反射机制获取MODEL
        /// </summary>
        /// <param name="_objectname"></param>
        /// <param name="_namespace"></param>
        /// <returns></returns>
        public virtual object GetModel(string _objectname, string _namespace = ConstUtil._ModelEntitySpaceName)
        {
            Assembly asb = Assembly.Load(_namespace);
            object h = Activator.CreateInstance(asb.GetType(_namespace + "." + _objectname));
            return h;
        }

        /// <summary>
        /// 把Model的数据映射到SqlParameter
        /// </summary>
        /// <param name="_param"></param>
        /// <param name="_emp"></param>
        public virtual void FillModel(SqlParameter[] _param, object _emp)
        {
            int _i = 0;
            var info = _emp.GetType();
            PropertyInfo[] Properties = info.GetProperties();
            for (int i = 0; i < Properties.Length; i++)
            {
                PropertyInfo myPropInfo = (PropertyInfo)Properties[i];
                object _value = myPropInfo.GetValue(_emp, null);
                if (null != _value)
                {
                    if (myPropInfo.Name.ToLower().IndexOf("uid") != -1 || myPropInfo.Name.ToLower() == "kzid" || myPropInfo.Name.ToLower() == "oid")
                    {
                        if (Convert.ToInt32(_value) < 1) {
                            continue;
                        }
                    }
                    if (_value.ToString().Trim() != ConstUtil._null)
                    {
                        _param[_i] = new SqlParameter(ConstUtil._At + myPropInfo.Name, _value);
                        _i = _i + 1;
                        if (_param.Length <= _i)
                        {
                            return;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 更新或添加SQL语句
        /// </summary>
        /// <param name="_proname">储存过程名称</param>
        /// <param name="_sql">更新或添加的SQL</param>
        /// <returns></returns>
        public int SaveOrUpdateSql(string _sql,string _proname = "SaveOrUpdateSql")
        {
            SqlParameter[] cmdparam = new SqlParameter[] { 
                new SqlParameter("@sql",_sql)
            };
            return ExecuteStorePro(_proname, cmdparam);
        }


        /// <summary>
        /// 执行存储过程
        /// </summary>
        /// <param name="_ProName">存储过程名称</param>
        /// <returns>影响的记录数</returns>
        public virtual int ExecuteStorePro(string _ProName, params SqlParameter[] cmdParms)
        {
            using (SqlConnection connection = new SqlConnection(ConStr))
            {
                using (SqlCommand cmd = new SqlCommand())
                {
                    try
                    {
                        PrepareCommand(cmd, connection, _ProName, cmdParms);
                        cmd.ExecuteNonQuery();
                        return (int)cmd.Parameters[ConstUtil._ReturnValue].Value;
                    }
                    catch(SqlException E)
                    {
                        LocalLog("过程名称:"+_ProName+"-"+E.Message);
                        return -1;
                    }
                }
            }
        }

        public string  ExecuteScalarByCommand(string sql)
        {
            using (SqlConnection connection = new SqlConnection(ConStr))
            {
                using (SqlCommand cmd = new SqlCommand())
                {
                    
                    try
                    {
                        cmd.Connection = connection;

                        cmd.CommandText = sql;
                        cmd.CommandType = CommandType.Text;
                        connection.Open();
                        object result = cmd.ExecuteScalar();
                        connection.Close();
                        connection.Dispose();
                        if (result == null)
                            return "";
                        else
                            return result.ToString();
                    }
                    catch (SqlException E)
                    {
                        LocalLog("错误语句:" + sql + "-" + E.Message);
                        return "";
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="conn"></param>
        /// <param name="cmdPro"></param>
        /// <param name="cmdParms"></param>
        public virtual void PrepareCommand(SqlCommand cmd, SqlConnection conn, string cmdPro,params SqlParameter[] cmdParms)
        {
            if (conn.State != ConnectionState.Open)
                conn.Open();
            cmd.Connection = conn;
            cmd.CommandText = cmdPro;
            cmd.CommandType = CommandType.StoredProcedure;
            if (cmdParms != null)
            {
                foreach (SqlParameter parm in cmdParms)
                    cmd.Parameters.Add(parm);
            }
            if (cmdPro.ToLower().IndexOf(ConstUtil._query) == -1 && cmdPro.ToLower().IndexOf("infobyopenIid") == -1) //查询时候不添加返回值
            {
                cmd.Parameters.Add(new SqlParameter(ConstUtil._ReturnValue, SqlDbType.Int, 4, ParameterDirection.ReturnValue, false, 0, 0, string.Empty, DataRowVersion.Default, null));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_stroeproname"></param>
        /// <param name="_modelpath"></param>
        /// <param name="_param"></param>
        /// <returns></returns>
        public IList<object> QueryObject_1(string _stroeproname, string _modelpath, params SqlParameter[] _param)
        {
            return QueryObject(_stroeproname, _modelpath,ConstUtil._ModelSpaceName,_param);
        }

        public object GetObjectByID_1(string _stroeproname, string _modelpath, params SqlParameter[] _param)
        {
            return GetObjectByID(_stroeproname, _modelpath, ConstUtil._ModelSpaceName, _param);
        }

        /// <summary>
        /// 执行存储过程总的单个查询方法
        /// </summary>
        /// <param name="_object"></param>
        /// <param name="_objectcount"></param>
        /// <param name="_storeproname"></param>
        /// <returns></returns>
        public virtual object FindByIdObject(object _object, int _objectcount, string _storeproname,string _modelpath)
        {
            try
            {
                SqlParameter[] objectparam = new SqlParameter[_objectcount];
                FillModel(objectparam, _object);
                return GetObjectByID_1(_storeproname, _modelpath, objectparam);
            }
            catch (Exception e)
            {
                LocalLog(_storeproname+":"+e.Message);
                return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_stroeproname"></param>
        /// <param name="_modelpath"></param>
        /// <param name="_namespace"></param>
        /// <param name="_param"></param>
        /// <returns></returns>
        public virtual object GetObjectByID(string _stroeproname, string _modelpath,string _namespace, params SqlParameter[] _param)
        {
            string _columnname = "";
            string _t = "";
            string _tt = "";
            try
            {
                using (SqlConnection connection = new SqlConnection(ConStr))
                {
                    using (SqlCommand cmd = new SqlCommand())
                    {
                        PrepareCommand(cmd, connection, _stroeproname, _param);
                        using (SqlDataReader dr = cmd.ExecuteReader())
                        {
                            Assembly asb = Assembly.Load(_namespace);
                            object hobject = Activator.CreateInstance(asb.GetType(_namespace + _modelpath));
                            if (dr.Read())
                            {
                                var info = hobject.GetType();
                                PropertyInfo[] Properties = info.GetProperties();
                                for (int j = 0; j < dr.FieldCount; j++)
                                {
                                    for (int i = 0; i < Properties.Length; i++)
                                    {
                                        PropertyInfo myPropInfo = (PropertyInfo)Properties[i];
                                        _columnname = dr.GetName(j).ToString();
                                        _t = dr[j].GetType().ToString();
                                        _tt = myPropInfo.PropertyType.ToString();
                                        if (myPropInfo.Name.ToLower() == dr.GetName(j).ToLower())
                                        {
                                            if (null != dr[j] && DBNull.Value != dr[j])
                                            {
                                                if (dr[j].ToString() == "")
                                                {
                                                    continue;
                                                }
                                                try
                                                {
                                                    if (dr[j].GetType() != myPropInfo.PropertyType)
                                                    {
                                                        if (myPropInfo.PropertyType == typeof(string))
                                                        {
                                                            myPropInfo.SetValue(hobject, dr[j].ToString(), null);
                                                        }
                                                        else
                                                            myPropInfo.SetValue(hobject, dr[j], null);
                                                    }
                                                    else
                                                    {
                                                        myPropInfo.SetValue(hobject, dr[j], null);
                                                    }
                                                }
                                                catch (Exception ex)
                                                {
                                                    LocalLog("错误信息111:" + ex.Message + " 存储过程名称:" + _stroeproname + " 列名:" + _columnname.ToString() + "[数据库里的类型:" + _t.ToString() + " 反射机制的类型:" + _tt.ToString() + "]" + _modelpath);
                                                }
                                            }
                                            else
                                            {
                                                try
                                                {
                                                    if (myPropInfo.PropertyType == typeof(string))
                                                    {
                                                        myPropInfo.SetValue(hobject, "", null);
                                                    }
                                                    else if (myPropInfo.PropertyType == typeof(DateTime?))
                                                    {
                                                        myPropInfo.SetValue(hobject, DateTime.Now, null);
                                                    }
                                                    else if (myPropInfo.PropertyType == typeof(decimal?))
                                                    {
                                                        decimal d = 0M;
                                                        myPropInfo.SetValue(hobject, d, null);
                                                    }
                                                    else
                                                        myPropInfo.SetValue(hobject, (myPropInfo.PropertyType == typeof(int?) ? 0 : (object)string.Empty), null);
                                                }
                                                catch (Exception ex)
                                                {
                                                    LocalLog("错误信息11:" + ex.Message + " 存储过程名称:" + _stroeproname + " 列名:" + _columnname.ToString() + "[数据库里的类型:" + _t.ToString() + " 反射机制的类型:" + _tt.ToString() + "]" + _modelpath);
                                                }
                                            }
                                            break;
                                        }
                                    }
                                }
                            }
                            return hobject;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                LocalLog(_stroeproname+":"+e.Message);
                return null;
            }
        }


        /// <summary>
        /// 直接返回数据集
        /// </summary>
        /// <param name="_stroeproname">存储过程名称</param>
        /// <param name="_param"></param>
        /// <returns></returns>
        public DataSet QueryObject(string _stroeproname, params SqlParameter[] _param)
        {
            try
            {
                using (SqlConnection connection = new SqlConnection(ConStr))
                {
                    using (SqlCommand cmd = new SqlCommand())
                    {
                        PrepareCommand(cmd, connection, _stroeproname, _param);
                        DataSet ds = new DataSet();
                        using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                        {
                            da.Fill(ds);
                        }
                        return ds;
                    }
                }
            }
            catch (Exception e)
            {
                LocalLog(_stroeproname+":"+e.Message);
                return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_stroeproname"></param>
        /// <returns></returns>
        public DataSet QueryObjectAll(string _stroeproname)
        {
            return QueryObject(_stroeproname, null);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_stroeproname"></param>
        /// <returns></returns>
        public DataSet QueryObjectAllSql(string _sql)
        {
            SqlParameter[] param = new SqlParameter[] { 
                new SqlParameter("@sql",_sql)
            };
            return QueryObject("QueryExecuteSql", param);
        }

        /// <summary>
        /// 公共查询信息
        /// </summary>
        /// <param name="employee"></param>parm
        /// <returns></returns>
        public IList<object> QueryObject(string _stroeproname, string _modelpath, string _namespace = ConstUtil._ModelSpaceName, params SqlParameter[] _param)
        {
            try
            {
                using (SqlConnection connection = new SqlConnection(ConStr))
                {
                    using (SqlCommand cmd = new SqlCommand())
                    {
                        PrepareCommand(cmd, connection, _stroeproname, _param);
                        using (SqlDataReader dr = cmd.ExecuteReader())
                        {
                            IList<object> _h = new List<object>();
                            AddEntityValue(_h, dr, _modelpath);
                            return _h;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                LocalLog(_stroeproname+":"+e.Message);
                return null;
            }
        }

        /// <summary>
        /// 把SqlDataReader 中的数据 填充到 IList 中
        /// </summary>
        /// <param name="_h"></param>
        /// <param name="asb"></param>
        /// <param name="dr"></param>
        /// <param name="_modelpath">Model的路径</param>
        public void AddEntityValue(IList<object> _h,SqlDataReader dr,string _modelpath)
        {
            string _columnname = "";
            string _t = "";
            string _tt = "";
            Assembly asb = Assembly.Load(ConstUtil._ModelSpaceName);
            while (dr.Read())
            {
                object hobject = Activator.CreateInstance(asb.GetType(ConstUtil._ModelSpaceName + _modelpath));
                var info = hobject.GetType();
                PropertyInfo[] Properties = info.GetProperties();
                for (int j = 0; j < dr.FieldCount; j++)
                {
                    for (int i = 0; i < Properties.Length; i++)
                    {
                        PropertyInfo myPropInfo = (PropertyInfo)Properties[i];

                        _columnname = dr.GetName(j).ToString();
                        _t = dr[j].GetType().ToString();
                        _tt = myPropInfo.PropertyType.ToString();

                        if (myPropInfo.Name.ToLower() == dr.GetName(j).ToLower())
                        {
                            if (null != dr[j] && DBNull.Value != dr[j])
                            {
                                if (dr[j].ToString() == "")
                                {
                                    continue;
                                }
                                try
                                {
                                    if (dr[j].GetType() != myPropInfo.PropertyType)
                                    {
                                        if (myPropInfo.PropertyType == typeof(string))
                                        {
                                            myPropInfo.SetValue(hobject, dr[j].ToString(), null);
                                        }
                                        else
                                            myPropInfo.SetValue(hobject, dr[j], null);
                                    }
                                    else
                                    {
                                        myPropInfo.SetValue(hobject, dr[j], null);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    LocalLog("错误信息:" + ex.Message + " 列名:" + _columnname.ToString() + "[数据库里的类型:" + _t.ToString() + " 反射机制的类型:" + _tt.ToString()+"]");
                                }
                            }
                            else
                            {
                                try
                                {
                                    if(myPropInfo.PropertyType==typeof(string))
                                    {
                                        myPropInfo.SetValue(hobject, "",null);
                                    }
                                    else if (myPropInfo.PropertyType == typeof(DateTime?))
                                    {
                                        myPropInfo.SetValue(hobject, DateTime.Now, null);
                                    }
                                    else if (myPropInfo.PropertyType == typeof(decimal?))
                                    {
                                        decimal d = 0M;
                                        myPropInfo.SetValue(hobject, d, null);
                                    }
                                    else if (myPropInfo.PropertyType == typeof(Decimal?))
                                    {
                                        decimal d = 0M;
                                        myPropInfo.SetValue(hobject, d, null);
                                    }
                                    else
                                    {
                                        myPropInfo.SetValue(hobject, (myPropInfo.PropertyType == typeof(int?) ? 0 : (object)string.Empty), null);
                                    }
                                }
                                catch(Exception ex)
                                {
                                    LocalLog("错误信息1a:" + ex.Message + " 列名a:" + _columnname.ToString() + "[数据库里的类型a:" + _t.ToString() + " 反射机制的类型:" + _tt.ToString() + "]");
                                }
                            }
                            break;
                        }
                    }
                }
                _h.Add(hobject);
            }
        }
    }
}
